﻿using System.Threading;
using ApiGateway.Config;
using ApiGateway.Helper;
using ApiGateway.Interface;
using RpcClient.Interface;
using RpcHelper;

namespace ApiGateway.PlugIn
{
    /// <summary>
    /// 全局限制
    /// </summary>
    internal class WholeLimitPlugIn : BasicPlugIn, IWholeLimitPlugIn
    {
        private LimitConfig _Config;
        private ILimit _Limit;
        private Timer _Timer;

        public override bool IsEnable => this._Config.LimitType != GatewayLimitType.不启用;

        public WholeLimitPlugIn() : base("WholeLimit")
        {
            this._Config = RpcClient.RpcClient.Config.GetConfigVal<LimitConfig>("gateway:wholeLimit", new LimitConfig());
            RpcClient.RpcClient.Config.AddRefreshEvent(this._Init);
        }

        private void _Init(IConfigServer server, string name)
        {
            if (name == "gateway:wholeLimit" || name.StartsWith("gateway:wholeLimit:"))
            {
                LimitConfig config = RpcClient.RpcClient.Config.GetConfigVal<LimitConfig>("gateway:wholeLimit", new LimitConfig());
                if (config.LimitType == GatewayLimitType.不启用 && this._Config.LimitType != GatewayLimitType.不启用)
                {
                    this._Config = config;
                    base._ChangeEvent();
                }
                else if (config.LimitType != GatewayLimitType.不启用 && this._Config.LimitType == GatewayLimitType.不启用)
                {
                    this._Config = config;
                    base._ChangeEvent();
                }
                else if (this._Limit.LimitType != config.LimitType)
                {
                    this._Config = config;
                    this._Limit = LimitHelper.GetLimit(config);
                    base._ChangeEvent();
                }
            }
        }
        protected override void _Dispose()
        {
            if (this._Config.LimitType == GatewayLimitType.不启用)
            {
                this._Timer?.Dispose();
                this._Timer = null;
                this._Limit = null;
            }
        }
        protected override void _InitPlugIn()
        {
            if (this._Config.LimitType != GatewayLimitType.不启用)
            {
                if (this._Limit == null)
                {
                    this._Limit = LimitHelper.GetLimit(this._Config);
                }
                if (this._Timer == null)
                {
                    this._Timer = new Timer(this._Refresh, null, 1000, 1000);
                }
            }
        }

        private void _Refresh(object state)
        {
            if (this._Limit != null)
            {
                int now = HeartbeatTimeHelper.HeartbeatTime;
                this._Limit.Refresh(now);
            }
        }
        public bool IsLimit()
        {
            if (this._Config.LimitType == GatewayLimitType.不启用)
            {
                return false;
            }
            return this._Limit.IsLimit();
        }
    }
}
